/**
 * 通用工具函数
 */

/**
 * 格式化金额显示
 * @param {number} amount - 金额
 * @param {number} decimals - 小数位数，默认2位
 * @returns {string} 格式化后的金额字符串
 */
export const formatAmount = (amount, decimals = 2) => {
  if (typeof amount !== 'number') {
    return '0.00'
  }
  return amount.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

/**
 * 格式化日期显示
 * @param {string|Date} date - 日期
 * @param {string} format - 格式，默认'YYYY-MM-DD'
 * @returns {string} 格式化后的日期字符串
 */
export const formatDate = (date, format = 'YYYY-MM-DD') => {
  const d = new Date(date)
  if (isNaN(d.getTime())) {
    return ''
  }
  
  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  const hour = String(d.getHours()).padStart(2, '0')
  const minute = String(d.getMinutes()).padStart(2, '0')
  const second = String(d.getSeconds()).padStart(2, '0')
  
  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hour)
    .replace('mm', minute)
    .replace('ss', second)
}

/**
 * 格式化时间显示
 * @param {string|Date} time - 时间
 * @returns {string} 格式化后的时间字符串 HH:mm
 */
export const formatTime = (time) => {
  if (typeof time === 'string' && /^\d{2}:\d{2}$/.test(time)) {
    return time
  }
  
  const d = new Date(time)
  if (isNaN(d.getTime())) {
    return '00:00'
  }
  
  const hour = String(d.getHours()).padStart(2, '0')
  const minute = String(d.getMinutes()).padStart(2, '0')
  return `${hour}:${minute}`
}

/**
 * 获取当前日期字符串
 * @returns {string} YYYY-MM-DD格式的日期
 */
export const getCurrentDate = () => {
  return formatDate(new Date())
}

/**
 * 获取当前时间字符串
 * @returns {string} HH:mm格式的时间
 */
export const getCurrentTime = () => {
  return formatTime(new Date())
}

/**
 * 获取月份的第一天和最后一天
 * @param {string} month - 月份，格式YYYY-MM
 * @returns {object} {startDate, endDate}
 */
export const getMonthRange = (month) => {
  const [year, monthNum] = month.split('-').map(Number)
  const startDate = `${year}-${String(monthNum).padStart(2, '0')}-01`
  const endDate = new Date(year, monthNum, 0)
  const endDateStr = formatDate(endDate)
  
  return { startDate, endDate: endDateStr }
}

/**
 * 获取本月的月份字符串
 * @returns {string} YYYY-MM格式的月份
 */
export const getCurrentMonth = () => {
  const now = new Date()
  const year = now.getFullYear()
  const month = String(now.getMonth() + 1).padStart(2, '0')
  return `${year}-${month}`
}

/**
 * 获取上个月的月份字符串
 * @returns {string} YYYY-MM格式的月份
 */
export const getLastMonth = () => {
  const now = new Date()
  const year = now.getFullYear()
  const month = now.getMonth()
  
  if (month === 0) {
    return `${year - 1}-12`
  } else {
    return `${year}-${String(month).padStart(2, '0')}`
  }
}

/**
 * 计算两个日期之间的天数
 * @param {string} startDate - 开始日期
 * @param {string} endDate - 结束日期
 * @returns {number} 天数
 */
export const getDaysBetween = (startDate, endDate) => {
  const start = new Date(startDate)
  const end = new Date(endDate)
  const diffTime = Math.abs(end - start)
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24))
}

/**
 * 验证金额格式
 * @param {number} amount - 金额
 * @returns {boolean} 是否有效
 */
export const validateAmount = (amount) => {
  return typeof amount === 'number' && 
         amount > 0 && 
         amount <= 999999.99 &&
         Number.isFinite(amount)
}

/**
 * 验证日期格式
 * @param {string} date - 日期字符串
 * @returns {boolean} 是否有效
 */
export const validateDate = (date) => {
  if (typeof date !== 'string') return false
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return false
  
  const d = new Date(date)
  return !isNaN(d.getTime()) && d.toISOString().slice(0, 10) === date
}

/**
 * 验证时间格式
 * @param {string} time - 时间字符串
 * @returns {boolean} 是否有效
 */
export const validateTime = (time) => {
  if (typeof time !== 'string') return false
  if (!/^\d{2}:\d{2}$/.test(time)) return false
  
  const [hour, minute] = time.split(':').map(Number)
  return hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59
}

/**
 * 防抖函数
 * @param {Function} func - 要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export const debounce = (func, wait) => {
  let timeout
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout)
      func(...args)
    }
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)
  }
}

/**
 * 节流函数
 * @param {Function} func - 要节流的函数
 * @param {number} limit - 时间间隔（毫秒）
 * @returns {Function} 节流后的函数
 */
export const throttle = (func, limit) => {
  let inThrottle
  return function executedFunction(...args) {
    if (!inThrottle) {
      func.apply(this, args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}

/**
 * 深拷贝对象
 * @param {any} obj - 要拷贝的对象
 * @returns {any} 拷贝后的对象
 */
export const deepClone = (obj) => {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  
  if (obj instanceof Date) {
    return new Date(obj.getTime())
  }
  
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item))
  }
  
  if (typeof obj === 'object') {
    const clonedObj = {}
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    return clonedObj
  }
}

/**
 * 生成唯一ID
 * @returns {string} 唯一ID
 */
export const generateId = () => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

/**
 * 显示成功提示
 * @param {string} message - 提示消息
 */
export const showSuccess = (message) => {
  wx.showToast({
    title: message,
    icon: 'success',
    duration: 2000
  })
}

/**
 * 显示错误提示
 * @param {string} message - 错误消息
 */
export const showError = (message) => {
  wx.showToast({
    title: message,
    icon: 'error',
    duration: 3000
  })
}

/**
 * 显示加载提示
 * @param {string} message - 加载消息
 */
export const showLoading = (message = '加载中...') => {
  wx.showLoading({
    title: message,
    mask: true
  })
}

/**
 * 隐藏加载提示
 */
export const hideLoading = () => {
  wx.hideLoading()
}

/**
 * 显示确认对话框
 * @param {string} message - 确认消息
 * @param {string} title - 标题
 * @returns {Promise<boolean>} 用户选择结果
 */
export const showConfirm = (message, title = '确认') => {
  return new Promise((resolve) => {
    wx.showModal({
      title,
      content: message,
      success: (res) => {
        resolve(res.confirm)
      },
      fail: () => {
        resolve(false)
      }
    })
  })
}

/**
 * 获取系统信息
 * @returns {Promise<object>} 系统信息
 */
export const getSystemInfo = () => {
  return new Promise((resolve, reject) => {
    wx.getSystemInfo({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 检查网络状态
 * @returns {Promise<object>} 网络状态信息
 */
export const getNetworkType = () => {
  return new Promise((resolve, reject) => {
    wx.getNetworkType({
      success: resolve,
      fail: reject
    })
  })
}

/**
 * 振动反馈
 * @param {string} type - 振动类型：'light' | 'medium' | 'heavy'
 */
export const vibrateShort = (type = 'light') => {
  if (wx.vibrateShort) {
    wx.vibrateShort({ type })
  }
}

/**
 * 计算数组总和
 * @param {Array} arr - 数字数组
 * @returns {number} 总和
 */
export const sum = (arr) => {
  return arr.reduce((total, num) => total + (Number(num) || 0), 0)
}

/**
 * 计算数组平均值
 * @param {Array} arr - 数字数组
 * @returns {number} 平均值
 */
export const average = (arr) => {
  if (arr.length === 0) return 0
  return sum(arr) / arr.length
}

/**
 * 数组去重
 * @param {Array} arr - 数组
 * @param {string} key - 对象数组的去重键名
 * @returns {Array} 去重后的数组
 */
export const unique = (arr, key) => {
  if (!key) {
    return [...new Set(arr)]
  }
  
  const seen = new Set()
  return arr.filter(item => {
    const value = item[key]
    if (seen.has(value)) {
      return false
    }
    seen.add(value)
    return true
  })
}

/**
 * 数组分组
 * @param {Array} arr - 数组
 * @param {string|Function} key - 分组键名或函数
 * @returns {object} 分组后的对象
 */
export const groupBy = (arr, key) => {
  return arr.reduce((groups, item) => {
    const groupKey = typeof key === 'function' ? key(item) : item[key]
    if (!groups[groupKey]) {
      groups[groupKey] = []
    }
    groups[groupKey].push(item)
    return groups
  }, {})
}

/**
 * 对象转查询字符串
 * @param {object} obj - 对象
 * @returns {string} 查询字符串
 */
export const objectToQuery = (obj) => {
  return Object.keys(obj)
    .filter(key => obj[key] !== undefined && obj[key] !== null && obj[key] !== '')
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
    .join('&')
}

/**
 * 查询字符串转对象
 * @param {string} query - 查询字符串
 * @returns {object} 对象
 */
export const queryToObject = (query) => {
  const params = {}
  const pairs = query.replace(/^\?/, '').split('&')
  
  pairs.forEach(pair => {
    const [key, value] = pair.split('=')
    if (key) {
      params[decodeURIComponent(key)] = decodeURIComponent(value || '')
    }
  })
  
  return params
}

/**
 * 判断是否为空值
 * @param {any} value - 值
 * @returns {boolean} 是否为空
 */
export const isEmpty = (value) => {
  if (value === null || value === undefined) return true
  if (typeof value === 'string') return value.trim() === ''
  if (Array.isArray(value)) return value.length === 0
  if (typeof value === 'object') return Object.keys(value).length === 0
  return false
}

/**
 * 安全的JSON解析
 * @param {string} str - JSON字符串
 * @param {any} defaultValue - 默认值
 * @returns {any} 解析结果
 */
export const safeJsonParse = (str, defaultValue = null) => {
  try {
    return JSON.parse(str)
  } catch (e) {
    console.warn('JSON解析失败:', e)
    return defaultValue
  }
}

/**
 * 安全的JSON字符串化
 * @param {any} obj - 对象
 * @param {string} defaultValue - 默认值
 * @returns {string} JSON字符串
 */
export const safeJsonStringify = (obj, defaultValue = '{}') => {
  try {
    return JSON.stringify(obj)
  } catch (e) {
    console.warn('JSON字符串化失败:', e)
    return defaultValue
  }
}